package com.huajin.codetest.util;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.util.LinkedHashMap;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;

import com.huajin.codetest.enums.HttpMethodEnum;

import lombok.extern.slf4j.Slf4j;

/**
 * HTTP工具类
 *
 * @author hongwei.lian
 * @date 2021年8月12日 下午8:16:58
 */
@Slf4j
public class HttpUtil {

    private HttpUtil() {}

    /**
     * 请求
     *
     * @param apiUrl
     * @param method
     * @param data
     * @param headers
     * @return
     * @throws Exception
     * @author hongwei.lian
     * @date 2021年8月12日 下午8:17:24
     */
    public static String send(String apiUrl, String method, String data, LinkedHashMap<String, String> headers) throws Exception {
        // 获得响应内容
        String httpResponseContent = null;
        HttpURLConnection httpURLConnection = null;
        int httpStatusCode = 0;
        String httpResponseMessage = null;
        try {
            log.info(">>>> 实际请求Url: " + apiUrl);
            // 建立连接
            URL url = new URL(apiUrl);
            httpURLConnection = (HttpURLConnection) url.openConnection();
            //设置请求超时时间
            httpURLConnection.setConnectTimeout(3000);
            httpURLConnection.setReadTimeout(3000);
            // 需要输出
            httpURLConnection.setDoOutput(true);
            // 需要输入
            httpURLConnection.setDoInput(true);
            // 不允许缓存
            httpURLConnection.setUseCaches(false);
            // HTTP请求方式
            httpURLConnection.setRequestMethod(method);
            // 设置Headers
            if (Objects.nonNull(headers)) {
                for (String key : headers.keySet()) {
                    httpURLConnection.setRequestProperty(key, headers.get(key));
                }
            }
            // 连接会话
            httpURLConnection.connect();
            // 建立输入流，向指向的URL传入参数
            DataOutputStream dos = new DataOutputStream(httpURLConnection.getOutputStream());
            // 设置请求参数
            dos.write(data.getBytes("UTF-8"));
            dos.flush();
            dos.close();
            // 获得响应状态(HTTP状态码)
            httpStatusCode = httpURLConnection.getResponseCode();
            // 获得响应消息(HTTP状态码描述)
            httpResponseMessage = httpURLConnection.getResponseMessage();
            // 获得响应内容
            if (HttpURLConnection.HTTP_OK == httpStatusCode) {
                // 返回响应结果
                httpResponseContent = getResponseContent(httpURLConnection.getInputStream());
            } else {
                // 返回非200状态时响应结果
                httpResponseContent = getResponseContent(httpURLConnection.getErrorStream());
                String msg = MessageFormat.format("请求失败: Http状态码 = {0} , {1}", httpStatusCode, httpResponseMessage);
                log.info(msg);
            }
        } catch (UnknownHostException e) {
            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
            Exception ex = new Exception(message);
            ex.initCause(e);
            throw ex;
        } catch (MalformedURLException e) {
            String message = MessageFormat.format("格式错误的URL: {0}", e.getMessage());
            Exception ex = new Exception(message);
            ex.initCause(e);
            throw ex;
        } catch (IOException e) {
            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
            Exception ex = new Exception(message);
            ex.initCause(e);
            throw ex;
        } catch (Exception e) {
            String message = MessageFormat.format("网络请求时发生异常: {0}", e.getMessage());
            Exception ex = new Exception(message);
            ex.initCause(e);
            throw ex;
        } finally {
            if (Objects.nonNull(httpURLConnection)) {
                httpURLConnection.disconnect();
            }
        }
        return httpResponseContent;
    }

    /***
     * 读取HttpResponse响应内容
     *
     * @return
     * @throws Exception
     */
    private static String getResponseContent(InputStream inputStream) throws Exception {
        StringBuffer contentBuffer = null;
        BufferedReader responseReader = null;
        try {
            contentBuffer = new StringBuffer();
            String readLine = null;
            responseReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            while ((readLine = responseReader.readLine()) != null) {
                contentBuffer.append(readLine);
            }
        } finally {
            if (Objects.nonNull(responseReader)) {
                responseReader.close();
            }
        }
        return contentBuffer.toString();
    }
    
    public static String requestHttpGet(String requestUrl){
        String output;
        StringBuilder builder = new StringBuilder();
        try {
            URL serverUrl = new URL(requestUrl);
            HttpURLConnection connection = (HttpURLConnection) serverUrl.openConnection();
            connection.setRequestMethod("GET");
            if (connection.getResponseCode() != 200) {
                throw new RuntimeException("HTTP GET Request Failed with Error code : " + connection.getResponseCode());
            }
            BufferedReader responseBuffer = new BufferedReader(new InputStreamReader((connection.getInputStream())));
            while ((output = responseBuffer.readLine()) != null) {
                builder.append(output);
            }
            connection.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return builder.toString();
    }
    
    public static String sendGet(String api) {
		String result = "";
		try {
			//LinkedHashMap<String, String> header = new LinkedHashMap<>(2);
			//header.put(Constants.CONTENT_TYPE, Constants.CONTENT_TYPE_VALUE);
			result = send(api, HttpMethodEnum.GET.name(), StringUtils.EMPTY, null);
		} catch (Exception e) {
			log.error("", e);
		}
		return result;
	}

}

